#!/usr/bin/env python
# -*- coding: utf-8 -*-
#===============================================================================
# Copyright 2011 zod.yslin
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# 
# Author: zod.yslin
# Email: 
# File Name: type.py
# Description: 
#   How to decide object's class type.
#
#  Method       Works on old-style classes?   Need to know type before calling?   Best For
#  type         No                            No                                  Nothing, really
#  isinstance   Yes                           Yes                                 Legitimate type-checking: When you're checking type against a known class
#  __class__    Yes                           No                                  Debugging: When you have no idea what class the instance is
#
# Edit History: 
#   2011-09-08    File created.
#===============================================================================
from types import *

# Instances of new-style classes
class NewClass(object): pass

new_class_instance = NewClass()

def function(): pass

string = 'This is a string!'

# Instances of old-style classes
class OldClass: pass

old_class_instance = OldClass()

print type(new_class_instance)
print new_class_instance.__class__
# both print "<class '__main__.new_class'>"

print type(function)
print function.__class__
# both print "<type 'function'>"

print type(string)
print string.__class__
# both print "<type 'str'>"

print type(old_class_instance)
# prints "<type 'instance'>"

print old_class_instance.__class__
# prints something like "class __main__.OldClass at 0x00F7F"
# Note that this is different than what was printed by type()

type(new_class_instance) == NewClass
isinstance(new_class_instance, NewClass)
new_class_instance.__class__ == NewClass
# All return True

type(function) == FunctionType # from 'types' module
isinstance(function, FunctionType)
function.__class__ == FunctionType
# All return True

type(string) == str # we could also use StringType from 'types' module
isinstance(string, str)
string.__class__ == str
# All return True

type(old_class_instance) == OldClass
# Returns False, even though old_class_instance is an instance of OldClass.
# 'type' just can't understand these.

isinstance(old_class_instance, OldClass)
old_class_instance.__class__ == OldClass
# Both return True as expected
